package arkham.gui;

import javax.swing.*;
import javax.swing.border.BevelBorder;

import arkham.net.ClientBase;
import arkham.net.ServerBase;
import arkham.util.ImageUtils;
import arkham.util.XmlTools;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;

public class WelcomeScreen extends JFrame implements ActionListener
{

	private static final long serialVersionUID = 4896523703290904136L;
	private int width, height;
	private ResizableImagePanel background;

	/* Components */
	private JPanel mainPanel;
	private ButtonGroup csOption;
	private JTextField usernameField;
	private JTextField hostField;
	private JFormattedTextField portField;
	private JButton connectButton, loadButton;
	private JLabel messageLabel;

	private String connectionString = "*";

	public WelcomeScreen()
	{
		width = 600;
		height = 600;
		this.setTitle("Arkham Horror");
		this.setSize(new Dimension(width, height));
		this.setIconImage(ImageUtils.loadImage("img/ahicon.png"));
		this.setResizable(false);
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		/* Initialize components */
		initBackground();
		initMainPanel();

		/* Set the initial position to middle of screen */
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Dimension screensize = toolkit.getScreenSize();
		this.setLocation((screensize.width - width) / 2, (screensize.height - height - 30) / 2);
		this.setVisible(true);
	}

	private void initBackground()
	{
		BufferedImage img = ImageUtils.loadImage("img/ahboxcover.jpg");
		background = new ResizableImagePanel(img);
		background.resizeImage(width, height);
		this.getContentPane().add(background);
	}

	private void initMainPanel()
	{
		mainPanel = new JPanel();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
		mainPanel.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createBevelBorder(BevelBorder.LOWERED),
				BorderFactory.createEmptyBorder(10, 10, 3, 10)));

		/* Username field */
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
		topPanel.add(new JLabel("Username: ", JLabel.LEFT));
		usernameField = new JTextField(15);
		usernameField.setDocument(new JTextFieldLimit(12));
		topPanel.add(usernameField);
		topPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

		/* Client option */
		JRadioButton clientOption = new JRadioButton("Client");
		clientOption.setActionCommand("Client");
		clientOption.setSelected(true);
		hostField = new JTextField(new String());
		/* Server Option */
		JRadioButton serverOption = new JRadioButton("Server");
		serverOption.setActionCommand("Server");
		portField = new JFormattedTextField(new DecimalFormat("#####"));
		portField.setDocument(new JTextFieldLimit(5));
		portField.setValue(11367);
		csOption = new ButtonGroup();
		csOption.add(clientOption);
		csOption.add(serverOption);

		/* Filling in the grid */
		JPanel csPanel = new JPanel();
		csPanel.setLayout(new GridBagLayout());
		GridBagConstraints gc = new GridBagConstraints();
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0;
		gc.gridx = 0;
		gc.gridy = 0;
		csPanel.add(clientOption, gc);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0.25;
		gc.gridx = 1;
		gc.gridy = 0;
		csPanel.add(new JLabel("Host: ", JLabel.RIGHT), gc);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0.75;
		gc.gridx = 2;
		gc.gridy = 0;
		csPanel.add(hostField, gc);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0;
		gc.gridx = 0;
		gc.gridy = 1;
		csPanel.add(serverOption, gc);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0.25;
		gc.gridx = 1;
		gc.gridy = 1;
		csPanel.add(new JLabel("Port: ", JLabel.RIGHT), gc);
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.weightx = 0.75;
		gc.gridx = 2;
		gc.gridy = 1;
		csPanel.add(portField, gc);
		csPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

		/* Buttons at the bottom */
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
		connectButton = new JButton("Connect... ");
		connectButton.setMnemonic('c');
		connectButton.setPreferredSize(new Dimension(95, 40));
		loadButton = new JButton(" Load...  ");
		loadButton.setEnabled(false);
		buttonPanel.add(Box.createRigidArea(new Dimension(25, 0)));
		buttonPanel.add(connectButton);
		buttonPanel.add(Box.createRigidArea(new Dimension(12, 0)));
		buttonPanel.add(loadButton);
		buttonPanel.add(Box.createRigidArea(new Dimension(25, 0)));
		buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		messageLabel = new JLabel(" ");
		messageLabel.setForeground(Color.red);

		/* Combining the elements */
		mainPanel.add(topPanel);
		mainPanel.add(csPanel);
		mainPanel.add(Box.createRigidArea(new Dimension(0, 5)));
		mainPanel.add(buttonPanel);
		mainPanel.add(messageLabel);
		background.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 250));
		background.add(mainPanel);

		/* Add action listeners */
		clientOption.setActionCommand("Client");
		clientOption.addActionListener(this);
		serverOption.setActionCommand("Server");
		serverOption.addActionListener(this);
		connectButton.setActionCommand("Connect");
		connectButton.addActionListener(this);
		loadButton.setActionCommand("Load");
		loadButton.addActionListener(this);

	}

	@Override
	public void actionPerformed(ActionEvent e) {

		if (e.getActionCommand().equals("Client"))
		{
			loadButton.setEnabled(false);
			connectButton.setText("Connect... ");
			connectButton.setMnemonic('c');
			hostField.setEnabled(true);
		}
		else if (e.getActionCommand().equals("Server"))
		{
			loadButton.setEnabled(true);
			connectButton.setText("New Game");
			connectButton.setMnemonic('n');
			hostField.setEnabled(false);
		}
		else if (e.getActionCommand().equals("Connect"))
		{
			int port = -1;
			if (usernameField.getText().equals("") ||
					!XmlTools.isExtAlphaNumeric(usernameField.getText()))
			{
				messageLabel.setText("Username must be alphanumeric.");
				return;
			}
			if (!XmlTools.isNumeric(portField.getText()))
			{
				messageLabel.setText("Port must be a number.");
				return;
			}
			else
			{
				port = Integer.parseInt(portField.getText());
				if (port < 1024 || port > 65535)
				{
					messageLabel.setText("Port must be between 1024-65535");
					return;
				}

			}

			if (csOption.getSelection().getActionCommand().equals("Client"))
			{
				// client selected
				if (hostField.getText().equals(""))
				{
					messageLabel.setText("Host must be specified.");
					return;
				}
				messageLabel.setText("Connecting...");
				ClientBase client = new ClientBase();
				boolean result = client.connect(hostField.getText(), port, usernameField.getText());
				if (result)
				{
					new Thread(client).start();
					LobbyScreen lscreen = new LobbyScreen(client, client.getLoadString());
					this.dispose();
				}
				else
				{
					messageLabel.setText("Failed to connect to server");
				}
			}
			else
			{
				// server selected
				messageLabel.setText("Starting new game...");
				ServerBase server = new ServerBase();
				server.setUsername(usernameField.getText());
				boolean result = server.listen(port);
				if (result)
				{
					// start the lobby and kill self
					new Thread(server).start();
					LobbyScreen lscreen = new LobbyScreen(server, connectionString);
					this.dispose();
				}
				else
				{
					messageLabel.setText("Failed to start listening server");
				}
			}
		}
		else if (e.getActionCommand().equals("Load"))
		{
			JOptionPane.showMessageDialog(this, "Sorry, this feature is not implemented yet.");
			messageLabel.setText(" ");
		}
	}



}
